package com.yy.customgeneric;

import java.util.ArrayList;
import java.util.List;

/**
 * chapter15  com.yy.customgeneric
 * 2023-06-22 22:07
 *
 * @author yy yuyue
 * description : 不可描述
 * @date 2023/6/22 22:07
 * <p>
 * 泛型的继承和通配符
 */

/*


?和E作用是一样的 但是这里 的参数一个 泛型集合 所以用 ? 而不是T等字母


通配符规定我要什么类型的容器， 泛型规定我要容器装什么


<?>:    支持任意泛型(无法添加元素,除了null,和<Object>的关系类型空和0的关系)


感觉?是给来方便不用取名的，有意义的，传啥类型用啥类型，而指定名字还得用变量


我好像理解这个问号了，首先这个是方法使用泛型，但是这个类不是泛型类，所以用字母是用不了的，
而用问号可以直接避免这个问题，不用去定义泛型类，就可以让方法使用泛型。我的个人理解是这样的

 */
public class GenericExtends {
    public static void main(String[] args) {

        Object o = new String("xx");

        //泛型没有继承性!!!
//        List<Object> list = new ArrayList<String>();
//        指定集合 就是Object类型  不管你是它爹 还是它娃  都不允许 !
/*
    不兼容的类型。实际为 java.util.ArrayList<java.lang.String>'，
    需要 'java.util.List<java.lang.Object>'
 */
        //举例说明下面三个方法的使用
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<AA> list3 = new ArrayList<>();
        List<BB> list4 = new ArrayList<>();
        List<CC> list5 = new ArrayList<>();

        //如果是 List<?> c ，可以接受任意的泛型类型
        printCollection1(list1);
        printCollection1(list2);
        printCollection1(list3);
        printCollection1(list4);
        printCollection1(list5);
        //只能在方法中使用泛型?

//        (List c)
        printCollection4(list1);
        printCollection4(list2);
        printCollection4(list3);
        printCollection4(list4);
        printCollection4(list5);


//        (List<Object> c)
        printCollection5(list1);
//        printCollection5(list2);x
//        printCollection5(list3);x
//        printCollection5(list4);x
//        printCollection5(list5);x

        //List<? extends AA> c: 表示 上限，可以接受 AA或者AA子类
//         printCollection2(list1);//x
//        printCollection2(list2);//x
        printCollection2(list3);//v
        printCollection2(list4);//v
        printCollection2(list5);//v

        //List<? super AA> c: 支持AA类以及AA类的父类,不限于直接父类
        printCollection3(list1);//v
//        printCollection3(list2);//
        printCollection3(list3);
//        printCollection3(list4);
//        printCollection3(list5);
    }

    public static void printCollection4(List c) {
        for (Object object : c) { // 通配符, 取出时，就是Object
            System.out.println(object);
        }
    }

    public static void printCollection5(List<Object> c) {
        for (Object object : c) { // 通配符, 取出时，就是Object
            System.out.println(object);
        }
    }

    //说明: List<?> 表示 任意的 泛型类型都可以接受
    //这里是创建对象, 使用泛型只不过把对象当做参数传入了!
    public static void printCollection1(List<?> c) {
        for (Object object : c) { // 通配符, 取出时，就是Object
            System.out.println(object);
        }
    }
//    List<Object> list1 = new ArrayList<>();
//    List<String> list2 = new ArrayList<>();
//    List<AA> list3 = new ArrayList<>();
//    List<BB> list4 = new ArrayList<>();
//    List<CC> list5 = new ArrayList<>();

    // ? extends AA 表示 上限，可以接受 AA或者AA子类
    public static void printCollection2(List<? extends AA> c) {
        for (Object object : c) {
            System.out.println(object);
        }
    }

    //? super 子类类名AA:支持AA类以及AA类的父类, 不限于直接父类
    //规定了泛型的下限
    public static void printCollection3(List<? super AA> c) {
        for (Object object : c) {
            System.out.println(object);
        }

    }
}

class AA {

}

class BB extends AA {

}

class CC extends BB {
}
